package parser.nodes;

// ArrayType = 'ARRAY' '[' IndexExpression ']' 'OF' Type

import codegen.AbstractDescr;
import codegen.ArrayDescr;
import codegen.CodeGen;
import codegen.ConstDescr;
import scanner.Token;
import static scanner.TokenType.*;

public class ArrayTypeNode extends Node {
    private IndexExpressionNode index;
    private TypeNode type;

    public ArrayTypeNode(IndexExpressionNode index, TypeNode type) {
        this.index = index;
        this.type = type;
    }
    
    @Override
    public void print() {
        p("ArrayType:");
        indent();
        p("ARRAY [");
        index.print();
        p("] OF");
        type.print();
        unindent();
    }

    @Override
    public void abstractPrint() {
        p("ARRAYTYPE");
        indent();
        index.abstractPrint();
        type.abstractPrint();
        unindent();
    }

    @Override
    public AbstractDescr getDescriptor(CodeGen c) throws CompileError {
        Token size = index.getSize();
        int elemCount = 0;
        if (size.type() == IDENTIFIER) {
            AbstractDescr descr = c.findDescr(size.toString());
            if (descr != null && descr instanceof ConstDescr)
                elemCount = ((ConstDescr)descr).getValue();
            else
                cerr("Unknown constant used to declare array. Found '" + size.toString() + "' at " + size.line()+":"+size.col());
        } else { //Aufgrund der implementierung der Declarations-Methode kann hier nur noch INTEGER kommen
            elemCount = Integer.parseInt(size.toString());
        }
        return new ArrayDescr(elemCount, type.getDescriptor(c));
    }
}
